﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using GMap.NET.WindowsForms.Markers;
using GMap.NET.WindowsForms;
using GMap.NET;
using Control;

namespace Vista
{
    public partial class VentanaPrincipal : Form
    {
        private CargaInicial cgInicial;
        private Aplicacion aplicacion;
        private BackgroundWorker bw_Simulacion;
        private int _posicionV = 1;
        private int[] _velocidad = {1,2,4,8,10,20,25,30,40,50};
        private GMapOverlay markersOverlay, routesOverlay;        
        private GMapMarker marcadorAnterior;
        private GMapRoute rutaAnterior;

        //simulacion
        private int _velocidadSimulacion = 1;        

        public VentanaPrincipal()
        {
            InitializeComponent();

        }

        private void VentanaPrincipal_Load(object sender, EventArgs e)
        {
            aplicacion = new Aplicacion();            
            mapa.MapProvider = GMap.NET.MapProviders.GoogleMapProvider.Instance;
            GMap.NET.GMaps.Instance.Mode = GMap.NET.AccessMode.ServerOnly;
            mapa.SetCurrentPositionByKeywords("Cali, Valle del Cauca, Colombia");
            mapa.MinZoom = 0;
            mapa.MaxZoom = 19;
            mapa.Zoom = 12;
            mapa.Position = new GMap.NET.PointLatLng(3.420733, -76.513168);              

            bw_Simulacion = new BackgroundWorker();
            bw_Simulacion.WorkerSupportsCancellation = true;
            bw_Simulacion.WorkerReportsProgress = true;
            bw_Simulacion.DoWork += new DoWorkEventHandler(bw_Simular);
            bw_Simulacion.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChangedSimulacion);
            bw_Simulacion.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompletedSimulacion);

        }

        private void bw_ProgressChangedSimulacion(object sender, ProgressChangedEventArgs e)
        {
            int porcentaje = int.Parse(e.ProgressPercentage.ToString());
            pgSimulacion.Value = porcentaje;
            pgSimulacion.Update();
            lbHora.Text = porcentaje + "";
        }

        private void bw_RunWorkerCompletedSimulacion(object sender, RunWorkerCompletedEventArgs e)
        {
            pgSimulacion.Value = 0;
            pgSimulacion.Update();
            lbHora.Text = "0";
            MessageBox.Show("Simulacion terminada");
            button2.Enabled = true;
            temporizadorEstadisticas.Stop();
            aplicacion.reiniciarListas();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            cgInicial = new CargaInicial(this, aplicacion);
            cgInicial.ShowDialog();
        }

        public void cargaDatosExitosa()
        {
            panelCarga.Visible = false;
            panel2.Visible = true;
            cargarEtiquetas();
        }

        public void cargarEtiquetas()
        {
            double[] coordenaas = aplicacion.darCoordenadas();
            string[] nombres = aplicacion.darNombresCoordenadas();
            string[] lineas = aplicacion.darNombresRutas();
            List<GMapMarkerGoogleGreen> marcadores = new List<GMapMarkerGoogleGreen>();
             markersOverlay = new GMapOverlay(mapa, "markers");
             routesOverlay = new GMapOverlay(mapa, "routes");
            for (int contador = 0; contador < coordenaas.Length; contador += 2)
            {
                GMapMarkerGoogleGreen marker = new GMapMarkerGoogleGreen(new PointLatLng(coordenaas[contador], coordenaas[contador + 1]));                
                marcadores.Add(marker);
            }

            for (int contar = 0; contar < marcadores.Count(); contar++)
            {
                GMapMarkerGoogleGreen marcador = marcadores[contar];
                marcador.Tag = nombres[contar];
                marcador.ToolTipText = nombres[contar];                
                markersOverlay.Markers.Add(marcador);

                listaEstaciones.Items.Add(nombres[contar]);
            }

            for (int contarLineas = 0; contarLineas < lineas.Length; contarLineas++)
            {
                listaRutas.Items.Add(lineas[contarLineas]);
            }
            
            mapa.Overlays.Add(markersOverlay);
            mapa.Overlays.Add(routesOverlay);            
        }

        private void button2_Click_1(object sender, EventArgs e)
        {
            if (bw_Simulacion.IsBusy != true)
            {
                bw_Simulacion.RunWorkerAsync();
                button2.Enabled = false;
                temporizadorEstadisticas.Start();
                aplicacion.generarPasajeros2();
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (_posicionV < 9)
            {
                _posicionV++;
                _velocidadSimulacion = (_velocidad[_posicionV]);
                lbVelocidad.Text = "x" + _velocidad[_posicionV];
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (_posicionV > 0)
            {
                _posicionV--;
                _velocidadSimulacion = (_velocidad[_posicionV]);
                lbVelocidad.Text = "x" + _velocidad[_posicionV];
            }
        }

        private void listaRutas_SelectedIndexChanged(object sender, EventArgs e)
        {
            lbNombre.Text = (string) listaRutas.SelectedItem;
            lbUtilitarioNombre.Text = "Buses en linea :";
            mapa.Zoom = 12;
            mapa.Position = new GMap.NET.PointLatLng(3.420733, -76.513168);
            List<PointLatLng> puntosRuta = new List<PointLatLng>();
            string[] estaciones = aplicacion.darParadasRuta((string)listaRutas.SelectedItem);

            for (int contador = 0; contador < estaciones.Length; contador++)
            {
                foreach (GMapMarker marcadorTemporal in markersOverlay.Markers)
                {
                    if (marcadorTemporal.ToolTipText == estaciones[contador])
                    {
                        puntosRuta.Add(marcadorTemporal.Position);
                    }
                }
            }
            
            pintarRuta(puntosRuta, Color.Magenta, 3);
        }

        private void listaEstaciones_SelectedIndexChanged(object sender, EventArgs e)
        {            
            lbNombre.Text = (string) listaEstaciones.SelectedItem;
            lbUtilitarioNombre.Text = "Pasajeros en estacion:";
            foreach (GMapMarker marcadorTemporal in markersOverlay.Markers)
            {
                if (marcadorTemporal.ToolTipText == (string) listaEstaciones.SelectedItem)
                {
                    if (marcadorAnterior != null){
                        marcadorAVerde(marcadorAnterior);
                    }
                    mapa.Position = marcadorTemporal.Position;
                    mapa.Zoom = 14;
                    marcadorAnterior = marcadorTemporal;
                    marcadorARojo(marcadorAnterior);
                    break;
                }
            }
            
        }

        private void marcadorARojo(GMapMarker marcador)
        {            
            markersOverlay.Markers.Remove(marcador);
            GMapMarkerGoogleRed nuevo = new GMapMarkerGoogleRed(marcador.Position);
            nuevo.ToolTipText = marcador.ToolTipText;
            markersOverlay.Markers.Add(nuevo);
        }

        private void marcadorAVerde(GMapMarker marcador)
        {
            markersOverlay.Markers.Remove(marcador);
            GMapMarkerGoogleGreen nuevo = new GMapMarkerGoogleGreen(marcador.Position);
            nuevo.ToolTipText = marcador.ToolTipText;
            markersOverlay.Markers.Add(nuevo);
        }

        private void pintarRuta(List<PointLatLng> puntos, Color color, int grosor)
        {
            if (rutaAnterior != null)
            {
                routesOverlay.Routes.Remove(rutaAnterior);
            }
                MapRoute route = new MapRoute(puntos, "rutaActual");
                GMapRoute r = new GMapRoute(route.Points, "rutaActual");
                r.Stroke.Width = grosor;
                r.Stroke.Color = color;
                routesOverlay.Routes.Add(r);
                rutaAnterior = r;            
        }

        public void bw_Simular(object sender, DoWorkEventArgs e)
        {

            aplicacion.abrirFlujo();

            int total = 1200;
            //int eventos = cgInicial.darPasajeros();
            int actual = 0;
            while (actual <= total)
            {
                BackgroundWorker worker = sender as BackgroundWorker;
                if ((worker.CancellationPending == true))
                {
                    e.Cancel = true;
                }
                else
                { // inicio loop de simulacion.                    
                    aplicacion.verificarNuevosPasajeros(actual);
                    //aplicacion.despacharBuses(actual);
                    //aplicacion.moverBuses();
                    aplicacion.verificarEstaciones();
                    // inicio avance simulacion.
                    Thread.Sleep(1000 / _velocidadSimulacion);
                    worker.ReportProgress(actual);
                    actual++;
                } // fin loop, avance simulacion.
            }

            aplicacion.cerrarFlujo(aplicacion.Escritor);

        }

        private void actualizarEstadoGeneral()
        {
            int pasajerosActivos = aplicacion.darPasajerosActivos();
            double cantidadEstaciones = aplicacion.darNumeroEstaciones();
            double promedio = ((double)pasajerosActivos/cantidadEstaciones);
            lbPasajerosActivos.Text = pasajerosActivos + "";
            lbPromedioPasajeros.Text = promedio + "";
            lbBusesActivos.Text = "";
        }

        private void temporizadorEstadisticas_Tick(object sender, EventArgs e)
        {
            actualizarEstadoGeneral();          
        }

        private void button5_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            DialogResult result = fbd.ShowDialog();
            String v = (fbd.SelectedPath) + "//registro.txt";
            aplicacion.RutaD = v;
        }
  
    }
}